package org.future.dataanalysis;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.future.dataanalysis.bean.DataUnit;
import org.future.dataanalysis.bean.Node;
import org.future.dataanalysis.bean.RecursionResult;
import org.future.dataanalysis.bean.Type;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Dongwei-Chen
 * @Date 2023/12/19 10:49
 * @Description
 */
public abstract class AnalysisServer implements Serializable {

    protected RecursionResult getData(JSON dataObj, Node node, RecursionResult data, Type type) {
        if (dataObj == null) {
            return data;
        }
        Map<String, String> dataMap = node.getDataMap();
        if (type == null) {
            type = node.getType();
        }
        switch (type) {
            case OBJECT:
                JSONObject jsonObject = (JSONObject) dataObj;
                fullData(data, dataMap, jsonObject);

                Map<String, Node> nodeMap = node.getNodeMap();
                if (nodeMap == null || nodeMap.isEmpty()) {
                    return data;
                }
                for (Map.Entry<String, Node> entry : nodeMap.entrySet()) {
                    String fieldName = entry.getKey();
                    JSON jsonObj = (JSON) jsonObject.get(fieldName);
                    Node childNode = entry.getValue();
                    data = getData(jsonObj, childNode, data, null);
                }
                break;
            case ARRAY:
                JSONArray jsonArray = (JSONArray) dataObj;
                for (Object json : jsonArray) {
                    JSON jsonObj = (JSON) json;
                    DataUnit dataUnit = data.getData();
                    DataUnit unit = new DataUnit();
                    unit.setTopic(dataUnit.getTopic());
                    unit.setDataArea(new HashMap<>(dataUnit.getDataArea()));
                    data.setData(unit);
                    data = getData(jsonObj, node, data, Type.OBJECT);
                    assert data != null;
                    if (node.isFlat()) {
                        data.pushFinalArea(data.getData());
                    }
                }
            default:
        }
        return data;
    }

    static void fullData(RecursionResult data, Map<String, String> dataMap, JSONObject jsonObject) {
        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
            String fieldName = entry.getKey();
            String reFieldName = entry.getValue();
            Object val = jsonObject.get(fieldName);
            if (val == null) {
                continue;
            }
            data.push(reFieldName, val);
        }
    }

    abstract RecursionResult analysis(JSONObject json, DataUnit dataUnit);

    public abstract boolean associatedArchives(DataUnit dataUnit, Map<String, String> redisMap);

}
